package com.huawei.demo;

import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ClientRequestException;
import com.huaweicloud.sdk.core.exception.ServerResponseException;
import com.huaweicloud.sdk.ga.v1.GaClient;
import com.huaweicloud.sdk.ga.v1.model.ClientAffinity;
import com.huaweicloud.sdk.ga.v1.model.HealthCheckProtocol;
import com.huaweicloud.sdk.ga.v1.model.PortRange;
import com.huaweicloud.sdk.ga.v1.model.UpdateAcceleratorRequest;
import com.huaweicloud.sdk.ga.v1.model.UpdateAcceleratorRequestBody;
import com.huaweicloud.sdk.ga.v1.model.UpdateAcceleratorResponse;
import com.huaweicloud.sdk.ga.v1.model.UpdateEndpointGroupRequest;
import com.huaweicloud.sdk.ga.v1.model.UpdateEndpointGroupRequestBody;
import com.huaweicloud.sdk.ga.v1.model.UpdateEndpointGroupResponse;
import com.huaweicloud.sdk.ga.v1.model.UpdateEndpointRequest;
import com.huaweicloud.sdk.ga.v1.model.UpdateEndpointRequestBody;
import com.huaweicloud.sdk.ga.v1.model.UpdateEndpointResponse;
import com.huaweicloud.sdk.ga.v1.model.UpdateHealthCheckRequest;
import com.huaweicloud.sdk.ga.v1.model.UpdateHealthCheckRequestBody;
import com.huaweicloud.sdk.ga.v1.model.UpdateHealthCheckResponse;
import com.huaweicloud.sdk.ga.v1.model.UpdateListenerRequest;
import com.huaweicloud.sdk.ga.v1.model.UpdateListenerRequestBody;
import com.huaweicloud.sdk.ga.v1.model.UpdateListenerResponse;
import com.huaweicloud.sdk.ga.v1.region.GaRegion;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.function.Function;

public class AcceleratorInstanceUpdateDemo {
    private static final Logger LOGGER = LoggerFactory.getLogger(AcceleratorInstanceUpdateDemo.class.getName());

    public static void main(String[] args) {
        String ak = "<your ak>";
        String sk = "<your sk>";

        ICredential auth = new BasicCredentials()
            .withAk(ak)
            .withSk(sk);

        GaClient client = GaClient.newBuilder()
            .withCredential(auth)
            .withRegion(GaRegion.valueOf("cn-east-3"))
            .build();

        updateAccelerator(client, "<your accelerator id>");

        updateListener(client, "<your listener id>");

        updateEndpointGroup(client, "<your endpointGroup id>");

        updateEndpoint(client, "<your endpointGroup id>", "<your endpoint id>");

        updateHealthCheck(client, "<your health check id>");
    }

    private static UpdateAcceleratorResponse updateAccelerator(GaClient client, String acceleratorId) {
        UpdateAcceleratorRequest request = new UpdateAcceleratorRequest();
        UpdateAcceleratorRequestBody body = new UpdateAcceleratorRequestBody();

        body.withAccelerator(updateAcceleratorOption -> {
            updateAcceleratorOption.withName("<your new accelerator name>");
            updateAcceleratorOption.withDescription("<your new accelerator description>");
        });
        request.withAcceleratorId(acceleratorId).withBody(body);
        Function<Void, UpdateAcceleratorResponse> task = (Void v) -> client.updateAccelerator(request);
        return execute(task);
    }

    private static UpdateListenerResponse updateListener(GaClient client, String listenerId) {
        UpdateListenerRequest request = new UpdateListenerRequest();
        UpdateListenerRequestBody body = new UpdateListenerRequestBody();

        body.withListener(updateListenerOption -> {
            updateListenerOption.withName("<your new listener name>");
            updateListenerOption.withDescription("<your new listener description>");
            updateListenerOption.withClientAffinity(ClientAffinity.NONE);
            updateListenerOption.withPortRanges(
                Collections.singletonList(new PortRange().withFromPort(5000).withToPort(5200)));
        });
        request.withListenerId(listenerId).withBody(body);
        Function<Void, UpdateListenerResponse> task = (Void v) -> client.updateListener(request);
        return execute(task);
    }

    private static UpdateEndpointGroupResponse updateEndpointGroup(GaClient client, String endpointGroupId) {
        UpdateEndpointGroupRequest request = new UpdateEndpointGroupRequest();
        UpdateEndpointGroupRequestBody body = new UpdateEndpointGroupRequestBody();
        body.withEndpointGroup(updateEndpointGroupOption -> {
            updateEndpointGroupOption.withName("<your new endpointGroup name>");
            updateEndpointGroupOption.withDescription("<your new endpointGroup description>");
            updateEndpointGroupOption.withTrafficDialPercentage(20);
        });
        request.withEndpointGroupId(endpointGroupId).withBody(body);
        Function<Void, UpdateEndpointGroupResponse> task = (Void v) -> client.updateEndpointGroup(request);
        return execute(task);
    }

    private static UpdateEndpointResponse updateEndpoint(GaClient client, String endpointGroupId, String endpointId) {
        UpdateEndpointRequest request = new UpdateEndpointRequest();
        UpdateEndpointRequestBody body = new UpdateEndpointRequestBody();
        body.withEndpoint(updateEndpointOption -> updateEndpointOption.withWeight(2));
        request.withEndpointGroupId(endpointGroupId).withEndpointId(endpointId).withBody(body);
        Function<Void, UpdateEndpointResponse> task = (Void v) -> client.updateEndpoint(request);
        return execute(task);
    }

    private static UpdateHealthCheckResponse updateHealthCheck(GaClient client, String healthCheckId) {
        UpdateHealthCheckRequest request = new UpdateHealthCheckRequest();
        UpdateHealthCheckRequestBody body = new UpdateHealthCheckRequestBody();
        body.withHealthCheck(updateHealthCheckOption -> {
            updateHealthCheckOption.withProtocol(HealthCheckProtocol.TCP);
            updateHealthCheckOption.withPort(3334);
            updateHealthCheckOption.withInterval(20);
            updateHealthCheckOption.withTimeout(20);
            updateHealthCheckOption.withMaxRetries(2);
            updateHealthCheckOption.withEnabled(true);
        });
        request.withHealthCheckId(healthCheckId).withBody(body);
        Function<Void, UpdateHealthCheckResponse> task = (Void v) -> client.updateHealthCheck(request);
        return execute(task);
    }

    private static <T> T execute(Function<Void, T> task) {
        T response = null;
        try {
            response = task.apply(null);
            LOGGER.info(response.toString());
        } catch (ClientRequestException e) {
            LOGGER.error(String.valueOf(e.getHttpStatusCode()));
            LOGGER.error(e.toString());
        } catch (ServerResponseException e) {
            LOGGER.error(String.valueOf(e.getHttpStatusCode()));
            LOGGER.error(e.getMessage());
        }
        return response;
    }
}
